
#ifndef __gui_graphH__
#define __gui_graphH__

#include "gui_widgets.h"

namespace WtfGui {
	class IGraphData: public virtual WtfEngine::IObservable {
	public:
		virtual ~IGraphData() {};

		virtual int getNumValues() = 0;
		virtual WtfEngine::String getLabel(int x) = 0;
		virtual float getValue(int x) = 0;

		GC_INTERFACE(IGraphData);
	};

	class Axes: public Widgets::Image {
	public:
		struct GraphEntry {
			IGraphData::tRef rData;
			fVector4D        vColour;
			WtfEngine::IFunctor<>::tRef rObserver;
			std::vector<float> mvYValues;

			GraphEntry(const IGraphData::tRef& data);
			GraphEntry(const IGraphData::tRef& data, const fVector4D& colour);

			inline bool operator == (const IGraphData::tRef& rGraph) const {
				return rData == rGraph;
			};
			inline bool operator == (const Axes::GraphEntry& graph) const {
				return rData == graph.rData;
			};
		};

		typedef WtfEngine::FunctorType<WtfEngine::String, float> tValueFormatter;

	protected:
		struct GraphXValue {
			WtfEngine::String sLabel;
			int iColumnWidth;
		};

		std::list<GraphEntry> mvGraphs;
		std::vector<GraphXValue> mvXValues;
		WtfEngine::String msXLabel, msYLabel;
		WtfEngine::FBOTexture::tRef mrTexture;
		tFont::tCacheRef mrFont;
		tValueFormatter::tRef mrValueFormatter;

	public:
		Axes(const WtfEngine::String& sXLabel, const WtfEngine::String& sYLabel);

		void AddGraph(const GraphEntry& rGraph);
		void RemoveGraph(const IGraphData::tRef& rGraph);

		inline void setValueFormatter(const WtfEngine::FunctorType<WtfEngine::String, float>::tRef rF) {
			mrValueFormatter = rF;
		};
		WtfEngine::String FormatValue(float v);

		/// Draws the graphs on the axes
		virtual void DrawGraphs(float fOffset, float fScale) = 0;
		void Update();

		virtual void Destroy();

		virtual void OnResize();

		GC_AUTOSIZE(Axes);
	};

	class LineGraph: public Axes {
	public:
		LineGraph(const WtfEngine::String& sXLabel, const WtfEngine::String& sYLabel);

		void DrawGraphs(float fOffset, float fScale);

		GC_AUTOSIZE(LineGraph);
	};
}; // WtfGui

#endif
